package com.lt.common;

import android.text.TextUtils;

import com.lt.exception.CustomException;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by tianlan on 2018/1/10.
 */

public class MatchHelper
{

    private static MatchHelper instance;

    private MatchHelper()
    {
    }

    public static MatchHelper getInstance()
    {
        if (instance == null)
        {
            synchronized (MatchHelper.class)
            {
                instance = new MatchHelper();
            }
        }
        return instance;
    }


    /**
     * 使用正则表达式匹配
     *
     * @param regex 正则表达式匹配
     * @param str   需要验证的字符串
     * @return 是否匹配
     */
    public boolean match(String regex, String str)
    {
        Pattern p = Pattern.compile(regex);
        return p.matcher(str).matches();
    }

    /**
     * 必须包含数字、字母
     */
    public boolean hasLetterAndDigit(String str)
    {
        boolean isDigit = false;
        boolean isLetter = false;
        for (int i = 0; i < str.length(); i++)
        {
            if (Character.isDigit(str.charAt(i)))
            {
                isDigit = true;
            }
            if (Character.isLetter(str.charAt(i)))
            {
                isLetter = true;
            }
        }
        return isDigit && isLetter;
    }

    /**
     * 正则：16进制
     */
    public static final String REGEX_HEX = "^[A-Fa-f0-9]+$";
    /**
     * 正则：数字和字母
     */
    public static final String REGEX_NUM_LETTER = "[A-Za-z0-9]*";
    /**
     * 正则：邮箱
     */
    public static final String REGEX_EMAIL_EXACT = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";

    /**
     * 正则：邮箱
     */
    public static final String REGEX_EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";

    /**
     * 正则：手机号（简单）
     */
    public static final String REGEX_MOBILE_SIMPLE = "^[1]\\d{10}$";
    /**
     * 只能输入汉字
     */
    public final String REGEX_HANZI = "^[\\u4e00-\\u9fa5]{0,}$";
    /**
     * 正则：手机号（精确）
     * <p>
     * 移动：134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、
     * 184、187、188、198
     * </p>
     * <p>
     * 联通：130、131、132、145、155、156、175、176、185、186、166
     * </p>
     * <p>
     * 电信：133、153、173、177、180、181、189、199
     * </p>
     * <p>
     * 全球星：1349
     * </p>
     * <p>
     * 虚拟运营商：170
     * </p>
     */
    public static final String REGEX_MOBILE_EXACT = "^(0|86|17951)?((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|(166)|19[8,9])\\d{8}$";

    public boolean isMobileNO(String mobiles)
    {
        Pattern p = Pattern
                .compile(REGEX_MOBILE_EXACT);
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    public boolean isMobileNO_S(String mobiles)
    {
        Pattern p = Pattern
                .compile(REGEX_MOBILE_SIMPLE);
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    public boolean isEmail(String email)
    {
        Pattern p = Pattern
                .compile(REGEX_EMAIL_EXACT);
        Matcher m = p.matcher(email);
        return m.matches();
    }

    /**
     * @param str
     * @return 判断是否全是数字
     */
    public boolean isNumeric(String str)
    {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        return isNum.matches();
    }


    /**
     * @param str
     * @return 是否是16进制的字符串
     */
    public boolean isHexNumberRex(String str)
    {
        Pattern pattern = Pattern.compile(REGEX_HEX);
        Matcher m = pattern.matcher(str);
        return m.matches();
    }

    /**
     * 验证输⼊的⾝份证号是否合法
     */
    public static boolean isLegalId(String id)
    {
        return id.toUpperCase().matches("(^\\d{15}$)|(^\\d{17}([0-9]|X)$)");
    }

    /**
     * @param name 检查中文姓名的合法性
     * @return 返回格式化之后中文姓名
     * @throws Exception 非法异常
     */
    public String checkChineseName(String name) throws Exception
    {
        if (TextUtils.isEmpty(name))
        {
            throw new Exception("姓名至少包含两位汉字");
        }
        //用于返回的姓名
        String resultName = name.replaceAll("　", "")
                .replaceAll(" ", "")
                .replaceAll("•", "·")
                .replaceAll("．", "·");
        //用户检查的姓名
        String checkName = name.replaceAll("　", "")
                .replaceAll(" ", "")
                .replaceAll("•", "")
                .replaceAll("．", "")
                .replaceAll("·", "");
        if (checkName.length() < 2)
        {
            throw new Exception("姓名至少包含两位汉字");
        }
        if (match(REGEX_HANZI, checkName))
        {
            if (checkName.startsWith("·"))
            {
                throw new Exception("姓名第一位不能为【·】");
            }
            if (checkName.endsWith("·"))
            {
                throw new Exception("姓名最后不能为【·】");
            }
            if (checkName.contains("··"))
            {
                throw new Exception("姓名不能有连续的【·】");
            }
        } else
        {
            throw new Exception("姓名中只能包含【汉字】和【·】");
        }
        return resultName;
    }

    /**
     * 身份证相关
     */
    // wi =2(n-1)(mod 11);加权因子
    final int[] wi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
    // 校验码
    final int[] vi = {1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2};
    private final int[] ai = new int[18];

    // 校验身份证的校验码
    public boolean cardNoVerify(String idcard)
    {
        if (TextUtils.isEmpty(idcard))
        {
            return false;
        }
        if (idcard.length() == 15)
        {
            idcard = uptoeighteen(idcard);
        }
        if (idcard.length() != 18)
        {
            return false;
        }
        String verify = idcard.substring(17, 18);
        return verify.equals(getVerify(idcard));
    }

    // 15位转18位
    private String uptoeighteen(String fifteen)
    {
        StringBuffer eighteen = new StringBuffer(fifteen);
        eighteen = eighteen.insert(6, "19");
        return eighteen.toString();
    }

    // 计算最后一位校验值
    private String getVerify(String eighteen)
    {
        int remain = 0;
        if (eighteen.length() == 18)
        {
            eighteen = eighteen.substring(0, 17);
        }
        if (eighteen.length() == 17)
        {
            int sum = 0;
            for (int i = 0; i < 17; i++)
            {
                String k = eighteen.substring(i, i + 1);
                ai[i] = Integer.valueOf(k);
            }
            for (int i = 0; i < 17; i++)
            {
                sum += wi[i] * ai[i];
            }
            remain = sum % 11;
        }
        return remain == 2 ? "X" : String.valueOf(vi[remain]);
    }

    //获取字符串中汉字的个数
    public int countChineseCharacters(String str)
    {
        char[] chars = str.toCharArray(); // 将字符串转换为char数组
        int chineseCount = 0;

        for (int i = 0; i < chars.length; i++)
        {
            if ((chars[i] & 0xF800) == 0xD800 && (chars[i + 1] & 0xFC00) == 0xDC00)
            {
                // Unicode范围内的高、低位合并表示一个汉字
                chineseCount++;
                i++; // 避免重复统计同一个汉字
            } else if ((chars[i] & 0xFFE0) == 0xC2A0 || (chars[i] & 0xFFFF) >= 0x4e00)
            {
                // 单个汉字或者其他非ASCII字符
                chineseCount++;
            }
        }

        return chineseCount;
    }
}
